import { addRoute, MiddlewareCreater, Route, RouteItem, ServerAPI } from "f2e-server3"
import fs from "fs"
import { API, DIR_TYPE } from "../common"
import { getDocDir, getLoginUser } from "../config"
import path from "path"
import { IncomingMessage } from "http"
import { getProfile } from "./profile"
import dayjs from "dayjs"
import { onImport } from "../preview"
import { hasAuthority } from "./app"

const download_file: ServerAPI<any, any, {
    params: {
        app_id: string;
        file_name: string;
    };
}> = async (_, ctx) => {
    const loginUser = getLoginUser(ctx)
    if (!loginUser) {
        return API.error("请先登录")
    }
    const { app_id, file_name } = ctx.params
    const filePath = path.join(getDocDir(), app_id, DIR_TYPE.FILES, file_name)
    if (!fs.existsSync(filePath)) {
        return ""
    }
    return fs.readFileSync(filePath)
}
addRoute("app/:app_id/files/:file_name", download_file, { type: "raw", sourceType: "binary" })
addRoute("preview/:app_id/files/:file_name", download_file, { type: "raw", sourceType: "binary" })

const onUpload: RouteItem["handler"] = async function (_, ctx) {
    const loginUser = getLoginUser(ctx)
    if (!loginUser) {
        return API.error("请先登录")
    }
    const params = new URLSearchParams(ctx.req.getQuery())
    const app_id = Number(params.get("app_id") || "")
    if (!app_id) {
        return API.error("缺少站点编号")
    }
    let filename = params.get("filename")
    if (!filename) {
        return API.error("缺少上传文件名称")
    }
    const profile = await getProfile()
    const app = profile.apps.find(item => item.id === app_id && hasAuthority(loginUser, item))
    if (!app) {
        return API.error("站点不存在")
    }
    let filePath = path.join(
        getDocDir(), app.id + "", DIR_TYPE.FILES, filename,
    )
    if (fs.existsSync(filePath)) {
        const timestamp = dayjs().format("YYYYMMDDHHmmss")
        filename = filename.replace(/\.([^.]+)$/, `_${timestamp}.$1`)
        filePath = filePath.replace(/\.([^.]+)$/, `_${timestamp}.$1`)
    }
    const req = (ctx.req as any).request as IncomingMessage
    return new Promise((resolve) => {
        const ws = fs.createWriteStream(filePath)
        ws.on('finish', () => {
            resolve(API.success({
                url: `${DIR_TYPE.FILES}/${filename}`
            }))
        })
        ws.on('error', (err) => {
            resolve(API.error(err.message))
        })
        req.pipe(ws)
    })
}

export const middle_upload: MiddlewareCreater = {
    name: "middle_upload",
    mode: ["prod", "dev"],
    execute(conf) {
        const router = new Route(conf)
        router.on('api/upload', onUpload)
        router.on('api/import', onImport)
        return {
            beforeRoute: router.execute,
        }
    },
}
